﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace SQLMetalOSUICtrl
{

    public partial class SQLMetalOSUICtrl : UserControl
    {
        #region private atributes
        //private copy of sqlmetaltool object
        private SQLMetalTool _sqlmetaltool;
        //step number handling
        private int step;
        //previous step numbre handled
        private int pStep;
        #endregion

        #region main event
        //output line event
        public event OutputPipeLine OutputLineEvent
        {
            add
            {
                if (_sqlmetaltool != null)
                    _sqlmetaltool.NewLine += value;
            }
            remove
            {
                if (_sqlmetaltool != null)
                    _sqlmetaltool.NewLine -= value;
            }
        }
        #endregion

        #region constructor
        public SQLMetalOSUICtrl()
        {
            InitializeComponent();

            //first step is 1
            this.step = 10;
            NextStep();

            //initializing privates variables and others...
            _sqlmetaltool = new SQLMetalTool();
            this.optIN.Checked = true;
            ConfigToolTipText();
            this.Width = 538;
            this.Height = 300;
            

            //Version
            this.lblVersion.Text = _sqlmetaltool.Version; //Assembly.GetExecutingAssembly().GetName().Version.ToString();

        }
        #endregion

        #region initial methods
        private void ConfigToolTipText()
        {
            // Set up the delays for the ToolTip.
            ttt_Dinamic.AutoPopDelay = 5000;
            ttt_Dinamic.InitialDelay = 1000;
            ttt_Dinamic.ReshowDelay = 500;
            // Force the ToolTip text to be displayed whether or not the form is active.
            ttt_Dinamic.ShowAlways = true;
            // apearence
            ttt_Dinamic.IsBalloon = true;

            //starting up texts
            ttt_Dinamic.SetToolTip(this.lblServer, Properties.Resources.txtServer);
            ttt_Dinamic.SetToolTip(this.lblCatalog, Properties.Resources.txtDataBase);
            ttt_Dinamic.SetToolTip(this.lblConnStr, Properties.Resources.txtConnStr);
            ttt_Dinamic.SetToolTip(this.lblPassword, Properties.Resources.txtPwd);
            ttt_Dinamic.SetToolTip(this.lblTimeOut, Properties.Resources.txtTimeout);
            ttt_Dinamic.SetToolTip(this.lblUser, Properties.Resources.txtUser);
            ttt_Dinamic.SetToolTip(this.lblInputFile, Properties.Resources.txtInput);
            ttt_Dinamic.SetToolTip(this.lblMap, Properties.Resources.txtMap);
            ttt_Dinamic.SetToolTip(this.lblDbml, Properties.Resources.txtDbml);
            ttt_Dinamic.SetToolTip(this.lblCode, Properties.Resources.txtCode);
            ttt_Dinamic.SetToolTip(this.lblLanguage, Properties.Resources.txtLanguage);
            ttt_Dinamic.SetToolTip(this.lblNamespace, Properties.Resources.txtNamespace);
            ttt_Dinamic.SetToolTip(this.lblContext, Properties.Resources.txtContext);
            ttt_Dinamic.SetToolTip(this.lblEntityBase, Properties.Resources.txtEntityBase);
            ttt_Dinamic.SetToolTip(this.lblPluralize, Properties.Resources.txtPluralize);
            ttt_Dinamic.SetToolTip(this.lblSerializacion, Properties.Resources.txtSerialization);

            //ttt_Dinamic.SetToolTip(this.lblVersion, Properties.Resources.txtVersion);

        }
        #endregion

        #region panel step2 methods
        private void btnSaveDbml_Click(object sender, EventArgs e)
        {
            //config interface
            // if dbml is used then map and code must be disabled
            this.txtPathDbml.Enabled = true;
            this.txtPathMap.Enabled = false;
            this.txtPathCode.Enabled = false;
            this.btnSaveMap.Enabled = this.txtPathCode.Enabled;
            this.gbLanguage.Enabled = this.txtPathCode.Enabled;

            using (SaveFileDialog saveDbml = new SaveFileDialog())
            {
                saveDbml.DefaultExt = "dbml";
                saveDbml.Filter = "dbml file (*.dbml)|*.dbml";
                saveDbml.ShowDialog(this.Parent);
                this.txtPathDbml.Text = saveDbml.FileName;
            }

            //all is ready
            pStep = step;
            step = 110;
            //preview available
            this.lblPreview.Enabled = true;


        }
        private void btnSaveCode_Click(object sender, EventArgs e)
        {
            //config interface
            // if code is used then map and dbml must be disabled
            this.txtPathDbml.Enabled = false;
            //this.txtPathMap.Enabled = false;
            this.txtPathCode.Enabled = true;
            this.btnSaveMap.Enabled = this.txtPathCode.Enabled;
            this.gbLanguage.Enabled = this.txtPathCode.Enabled;

            using (SaveFileDialog saveCode = new SaveFileDialog())
            {
                saveCode.DefaultExt = "cs";
                saveCode.Filter = "Visual C# code file (*.cs)|*.cs|Visual Basic .NET code file (*.vb)|*.vb";
                saveCode.ShowDialog(this.Parent);
                this.txtPathCode.Text = saveCode.FileName;
            }

            //select C# or VB.NET 
            if (this.txtPathCode.Text.EndsWith("cs"))
                this.cbLanguages.SelectedIndex = 0;
            else
                this.cbLanguages.SelectedIndex = 1;

            //all is ready,,,
            pStep = step;
            step = 120;
            //preview available
            this.lblPreview.Enabled = true;
        }
        private void btnSaveMap_Click(object sender, EventArgs e)
        {
            //config interface
            // if map is used then dbml and code must be disabled
            this.txtPathDbml.Enabled = false;
            this.txtPathMap.Enabled = true;
            this.txtPathCode.Enabled = true;
            this.gbLanguage.Enabled = this.txtPathCode.Enabled;

            using (SaveFileDialog saveMap = new SaveFileDialog())
            {
                saveMap.DefaultExt = "cs";
                saveMap.Filter = "Map file (*.map)|*.map";
                saveMap.ShowDialog(this.Parent);
                this.txtPathMap.Text = saveMap.FileName;
            }

            //all is ready,,,
            pStep = step;
            step = 130;
            //preview available
            this.lblPreview.Enabled = true;
        }
        private void cbLanguages_SelectedIndexChanged(object sender, EventArgs e)
        {
            //let's change correct output file extension
            if ((sender as ComboBox).SelectedIndex == 1)
                this.txtPathCode.Text = this.txtPathCode.Text.Replace("cs", "vb");
            else
                this.txtPathCode.Text = this.txtPathCode.Text.Replace("vb", "cs");

        }
        #endregion

        #region panel step1 methods
        private void optIN_CheckedChanged(object sender, EventArgs e)
        {
            pStep = 100;
            step = 100;
            //TODO method not optimized
            if (this.optDS.Checked == true)
            {
                //disable connection string option
                this.lblConnStr.Enabled = false;
                this.txtCstr.Enabled = false;
                this.btnGenerateConnString.Enabled = false;
                //disable input file option
                this.lblInputFile.Enabled = false;
                this.txtInputFile.Enabled = false;
                this.btnInputFile.Enabled = false;
                //enable database server connection options
                this.cbCatalog.Enabled = true;
                this.cbServers.Enabled = true;
                this.lblServer.Enabled = true;
                this.lblCatalog.Enabled = true;
                this.txtUser.Enabled = true;
                this.lblUser.Enabled = true;
                this.txtPassword.Enabled = true;
                this.lblPassword.Enabled = true;
                this.lblTimeOut.Enabled = true;
                this.txtTimeOut.Enabled = true;
                this.chkSDFPwd.Enabled = false;

            }
            else if (this.optCS.Checked == true)
            {
                //enable connection string option
                this.lblConnStr.Enabled = true;
                this.txtCstr.Enabled = true;
                this.btnGenerateConnString.Enabled = true;
                //disable input file option
                this.lblInputFile.Enabled = false;
                this.txtInputFile.Enabled = false;
                this.btnInputFile.Enabled = false;
                //disable database server connection options
                this.cbCatalog.Enabled = false;
                this.cbServers.Enabled = false;
                this.lblServer.Enabled = false;
                this.lblCatalog.Enabled = false;
                this.txtUser.Enabled = false;
                this.lblUser.Enabled = false;
                this.txtPassword.Enabled = false;
                this.lblPassword.Enabled = false;
                this.lblTimeOut.Enabled = false;
                this.txtTimeOut.Enabled = false;
                this.chkSDFPwd.Enabled = false;

            }
            else
            {
                //enable connection string option
                this.lblConnStr.Enabled = false;
                this.txtCstr.Enabled = false;
                this.btnGenerateConnString.Enabled = false;
                //disable input file option
                this.lblInputFile.Enabled = true;
                this.txtInputFile.Enabled = true;
                this.btnInputFile.Enabled = true;
                //disable database server connection options
                this.cbCatalog.Enabled = false;
                this.cbServers.Enabled = false;
                this.lblServer.Enabled = false;
                this.lblCatalog.Enabled = false;
                this.txtUser.Enabled = false;
                this.lblUser.Enabled = false;
                this.txtPassword.Enabled = false;
                this.lblPassword.Enabled = false;
                this.lblTimeOut.Enabled = false;
                this.txtTimeOut.Enabled = false;
                this.chkSDFPwd.Enabled = true;

            }
        }
        private void btnInputFile_Click(object sender, EventArgs e)
        {
            this.openFileDialog.DefaultExt = "sdf";
            this.openFileDialog.Filter = "SQL Server Compact Edition database files(*.sdf)|*.sdf|"+
                "SQL Server Express Edition database files(*.mdf)|*.mdf|" +
                "Dbml intermediate files(*.dbml)|*.dbml";
            this.openFileDialog.ShowDialog(this.Parent);
            this.txtInputFile.Text = this.openFileDialog.FileName;
        }
        private void optCS_CheckedChanged(object sender, EventArgs e)
        {
            pStep = step;
            step = 80;
        }
        private void btnGenerateConnString_Click(object sender, EventArgs e)
        {
            System.Data.SqlClient.SqlConnectionStringBuilder strConnBuild =
                new System.Data.SqlClient.SqlConnectionStringBuilder();

            strConnBuild["Data Source"] = "(local)";
            strConnBuild["Initial Catalog"] = "AdventureWorks";

            strConnBuild["User"] = "";
            strConnBuild["Password"] = "";
            //or 
            strConnBuild["integrated Security"] = true;

            frmResults res = new frmResults();
            res.propertyGrid1.SelectedObject = strConnBuild;
            res.ShowDialog(base.Parent);

            this.txtCstr.Text =  strConnBuild.ConnectionString;


        }
        private void optDS_CheckedChanged(object sender, EventArgs e)
        {
            pStep = step;
            step = 70;
            //TODO method not optimized
            if (this.optDS.Checked == true)
            {
                //disable connection string option
                this.lblConnStr.Enabled = false;
                this.txtCstr.Enabled = false;
                this.btnGenerateConnString.Enabled = false;
                //disable input file option
                this.lblInputFile.Enabled = false;
                this.txtInputFile.Enabled = false;
                this.btnInputFile.Enabled = false;
                //enable database server connection options
                this.cbCatalog.Enabled = true;
                this.cbServers.Enabled = true;
                this.lblServer.Enabled = true;
                this.lblCatalog.Enabled = true;
                this.txtUser.Enabled = true;
                this.lblUser.Enabled = true;
                this.txtPassword.Enabled = true;
                this.lblPassword.Enabled = true;
                this.lblTimeOut.Enabled = true;
                this.txtTimeOut.Enabled = true;


            }
            else if (this.optCS.Checked == true)
            {
                //enable connection string option
                this.lblConnStr.Enabled = true;
                this.txtCstr.Enabled = true;
                this.btnGenerateConnString.Enabled = true;
                //disable input file option
                this.lblInputFile.Enabled = false;
                this.txtInputFile.Enabled = false;
                this.btnInputFile.Enabled = false;
                //disable database server connection options
                this.cbCatalog.Enabled = false;
                this.cbServers.Enabled = false;
                this.lblServer.Enabled = false;
                this.lblCatalog.Enabled = false;
                this.txtUser.Enabled = false;
                this.lblUser.Enabled = false;
                this.txtPassword.Enabled = false;
                this.lblPassword.Enabled = false;
                this.lblTimeOut.Enabled = false;
                this.txtTimeOut.Enabled = false;

            }
            else 
            {
                //enable connection string option
                this.lblConnStr.Enabled = false;
                this.txtCstr.Enabled = false;
                this.btnGenerateConnString.Enabled = false;
                //disable input file option
                this.lblInputFile.Enabled = true;
                this.txtInputFile.Enabled = true;
                this.btnInputFile.Enabled = true;
                //disable database server connection options
                this.cbCatalog.Enabled = false;
                this.cbServers.Enabled = false;
                this.lblServer.Enabled = false;
                this.lblCatalog.Enabled = false;
                this.txtUser.Enabled = false;
                this.lblUser.Enabled = false;
                this.txtPassword.Enabled = false;
                this.lblPassword.Enabled = false;
                this.lblTimeOut.Enabled = false;
                this.txtTimeOut.Enabled = false;

            }
        }
        #endregion

        #region navigate methods
        private void lblNext_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            //NOTE: if not output file is set, the output results
            //will be redirected to _newLine delegate
            bool nextStep = false;

            switch (step)
            {
                case (100):
                    //if inputfile mode is selected...
                    //the filename is mandatory
                    if (this.txtInputFile.Text.Length == 0)
                        this.txtInputFile.Focus();
                    else
                        nextStep = true;
                        //chek out wheter the sdf file needs a pwd
                    if (chkSDFPwd.Checked)
                        this.txtInputFile.Text += "\" /password:" + txtSDFPwd.Text + "\"";
                    break;
                case (80):
                    //if connectionsstring or database server 
                    // mode is selected...
                    //we attempt to connect to first
                    if (!ConnectionTester(this.txtCstr.Text))
                        return;
                    pStep = step;
                    step = 90;
                    nextStep = true;
                    break;
                case (70):
                    //if connectionsstring or database server 
                    // mode is selected...
                    //we attempt to connect to first
                    if (!ConnectionTester(this.cbServers.Text,this.cbCatalog.Text,
                        this.txtUser.Text, this.txtPassword.Text))
                        return;
                    pStep = step;
                    step = 90;
                    nextStep = true;
                    break;
                case 110: //create dbml with output file
                    if (this.txtPathDbml.Text.Length > 0) nextStep = true;
                    break;
                case 111: //create dbml without output file
                    if (this.txtPathDbml.Text.Length > 0) nextStep = true; break;
                case 120://create code with output file
                    if (this.txtPathCode.Text.Length > 0) nextStep = true; break;
                case 121://create code without output file
                    if (this.txtPathCode.Text.Length > 0) nextStep = true; break;
                case 130://create code with output file
                    //let sqlmetal.exe show what's wrong
                    /*if ((this.txtPathMap.Text.Length > 0) &&
                        (this.txtPathCode.Text.Length > 0)) nextStep = true;
                    else
                        _sqlmetaltool._newline("Incorrect parameters.");*/
                    nextStep = true;
                    break;
                case 131://create code without output file
                    if (MessageBox.Show("SQLMetal.exe is going to show you a preview...", "SQLMetal.exe", MessageBoxButtons.OK) == DialogResult.OK)
                        //TODO: At this version,this option is not allowed
                        //_sqlmetaltool.GenerateMap(this.txtInputFile.Text, string.Empty);
                        _sqlmetaltool.NewLine("The preview option is not supported yet. Try next step... ");
                    break;
                
                default:
                    break;
            }
            
            //all processed OK?
            if (nextStep == true)
                NextStep();
        }
        private void NextStep()
        {
            this.Cursor = Cursors.WaitCursor;
            
            switch (step)
            {
                case 10:
                    ShowOnlyPanel(step1);
                    break;
                case 90:
                    
                case 100:
                    ShowOnlyPanel(step2);
                    break;
                case 110: //create dbml with output file
                    if (MessageBox.Show("The process is going to start up, are you sure?", "SQLMetal.exe", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        _sqlmetaltool.GenerateDBML(this.txtInputFile.Text, this.txtPathDbml.Text);
                    break;
                case 111: //create dbml without output file
                    if (MessageBox.Show("SQLMetal.exe is going to show you a preview...", "SQLMetal.exe", MessageBoxButtons.OK) == DialogResult.OK)
                        _sqlmetaltool.GenerateDBML(this.txtInputFile.Text, string.Empty);
                    break;
                case 120://create code with output file
                    if (MessageBox.Show("The process is going to start up, are you sure?", "SQLMetal.exe", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        _sqlmetaltool.GenerateCode(this.txtInputFile.Text, this.txtPathCode.Text, this.txtNamespace.Text);
                    break;
                case 121://create code without output file
                    if (MessageBox.Show("SQLMetal.exe is going to show you a preview...", "SQLMetal.exe", MessageBoxButtons.OK) == DialogResult.OK)
                        _sqlmetaltool.GenerateCode(this.txtInputFile.Text, string.Empty, this.txtNamespace.Text);
                    break;
                case 130://create code with output file
                    if (MessageBox.Show("The process is going to start up, are you sure?", "SQLMetal.exe", MessageBoxButtons.YesNo) == DialogResult.Yes)
                        _sqlmetaltool.GenerateMap(this.txtInputFile.Text, this.txtPathMap.Text, this.txtPathCode.Text, this.txtNamespace.Text);
                    break;
                case 131://create code without output file
                    if (MessageBox.Show("SQLMetal.exe is going to show you a preview...", "SQLMetal.exe", MessageBoxButtons.OK) == DialogResult.OK)
                        //TODO: At this version,this option is not allowed
                        //_sqlmetaltool.GenerateMap(this.txtInputFile.Text, string.Empty);
                        _sqlmetaltool.NewLine("At this version,this option preview is not allowed. Try next step... ");
                    break;
                default:
                    throw new NotImplementedException();
                    break;
            }

            

            //enbaling previous step
            this.lblPreviuos.Enabled = true;

            //TODO: modify screen cursor behavior
            this.Cursor = Cursors.Default;
        }
        private void ShowOnlyPanel(Panel panel)
        {
            panel.Location = new Point(4, 3);
            panel.Visible = true;
            panel.BringToFront();
        }
        private void lblPreview_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            step += 1;
            NextStep();
            step -= 1;
        }
        private void lblPreviuos_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            step = 10;
            NextStep();
            step = pStep;
            lblPreviuos.Enabled = false;
            this.Cursor = Cursors.Default;
        }
        #endregion

        #region miscelanea methods
        private void lblVersion_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            _sqlmetaltool.GetSqlMetalInformation();
        }
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._sqlmetaltool.GetHelp();
        }

        public bool ConnectionTester(string connectionString)
        {
            
            System.Data.Common.DbConnection connection;
            bool res = false;

            try
            {
                connection =
                    new System.Data.SqlClient.SqlConnection(connectionString);

                connection.Open();
                res = true;
            }
            catch (System.Data.Common.DbException oldbex)
            {
                //use Microsoft.SqlServer.ExceptionHandler better
                _sqlmetaltool.NewLine(oldbex.Message);
            }
            catch (Exception ex)
            {
                //use Microsoft.SqlServer.ExceptionHandler better
                _sqlmetaltool.NewLine(ex.Message);
            }

            finally
            {
                connection = null;
            }

            return res;

        }
        public bool ConnectionTester(string server, string database,
            string user, string password)
        {
            System.Data.SqlClient.SqlConnectionStringBuilder strConnBuild =
                new System.Data.SqlClient.SqlConnectionStringBuilder();


            strConnBuild["Data Source"] = server;
            strConnBuild["Initial Catalog"] = database;

            if ((user.Length > 0) && (password.Length > 0))
            {
                strConnBuild["Integrated security"] = false;
                strConnBuild["User"] = user;
                strConnBuild["Password"] = password;
            }
            else
                strConnBuild["Integrated security"] = true;

            return ConnectionTester(strConnBuild.ConnectionString);

        }
        #endregion

        private void SQLMetalOSUICtrl_Load(object sender, EventArgs e)
        {
            //TODO: Donde carajo metemos esto. Si lo pongo falla al cargar el formulario
            //succesfully started.
            //here sqlmetal.exe has been found...
#if !DEBUG
            //_sqlmetaltool.GetStatus(); 
#endif
        }

        private void chkSDFPwd_CheckedChanged(object sender, EventArgs e)
        {
            this.txtSDFPwd.Visible = chkSDFPwd.Checked;
            if (!this.txtSDFPwd.Visible) this.txtSDFPwd.Text = string.Empty;
        }

     
    }
}


